package com.lds.config.center.server.business.item.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lds.config.center.common.model.item.request.ItemBaseBatchCreateRequest;
import com.lds.config.center.common.model.item.request.ItemBaseBatchDeleteRequest;
import com.lds.config.center.common.model.item.request.ItemBaseBatchUpdateRequest;
import com.lds.config.center.common.model.item.request.ItemBaseCreateRequest;
import com.lds.config.center.common.model.item.request.ItemBaseDeleteRequest;
import com.lds.config.center.common.model.item.request.ItemBaseGetByIdRequest;
import com.lds.config.center.common.model.item.request.ItemBaseGetByIdsRequest;
import com.lds.config.center.common.model.item.request.ItemBaseGetByKeyRequest;
import com.lds.config.center.common.model.item.request.ItemBaseListPageRequest;
import com.lds.config.center.common.model.item.request.ItemBaseListRequest;
import com.lds.config.center.common.model.item.request.ItemBaseUpdateRequest;
import com.lds.config.center.common.model.item.response.ItemBaseBatchCreateResponse;
import com.lds.config.center.common.model.item.response.ItemBaseBatchDeleteResponse;
import com.lds.config.center.common.model.item.response.ItemBaseBatchUpdateResponse;
import com.lds.config.center.common.model.item.response.ItemBaseDeleteResponse;
import com.lds.config.center.common.model.item.response.ItemBaseListResponse;
import com.lds.config.center.common.model.item.response.ItemBaseResponse;
import com.lds.config.center.server.business.item.converter.ItemBaseCreateRequestToEntityConverter;
import com.lds.config.center.server.business.item.converter.ItemBaseGetByKeyRequestToEntityConverter;
import com.lds.config.center.server.business.item.converter.ItemBaseListPageRequestToEntityConverter;
import com.lds.config.center.server.business.item.converter.ItemBaseListRequestToEntityConverter;
import com.lds.config.center.server.business.item.converter.ItemBaseUpdateRequestToEntityConverter;
import com.lds.config.center.server.business.item.converter.ItemToBaseResponseConverter;
import com.lds.config.center.server.business.item.entity.Item;
import com.lds.config.center.server.business.item.mapper.ItemMapper;
import com.lds.config.center.server.business.item.service.ItemBaseService;
import com.lds.management.center.common.model.db.OrderBy;
import com.lds.management.center.common.model.db.PageResult;
import com.lds.management.center.common.model.dto.ResultDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 基础服务实现类
 *
 * @author lidongsheng
 * @since 2025-06-30
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ItemBaseServiceImpl implements ItemBaseService {
    private final ItemMapper itemMapper;
    private final ItemBaseCreateRequestToEntityConverter itemBaseCreateRequestToEntityConverter;
    private final ItemBaseUpdateRequestToEntityConverter itemBaseUpdateRequestToEntityConverter;
    private final ItemBaseListRequestToEntityConverter itemBaseListRequestToEntityConverter;
    private final ItemToBaseResponseConverter itemToBaseResponseConverter;
    private final ItemBaseListPageRequestToEntityConverter itemBaseListPageRequestToEntityConverter;
    private final ItemBaseGetByKeyRequestToEntityConverter itemBaseGetByKeyRequestToEntityConverter;

    @Override
    @Transactional
    public ResultDTO<ItemBaseResponse> createItem(ItemBaseCreateRequest request) {
        try {
            Item item = itemBaseCreateRequestToEntityConverter.convert(request);
            itemMapper.insert(item);
            ItemBaseResponse response = itemToBaseResponseConverter.convert(item);
            return ResultDTO.success(response);
        } catch (DuplicateKeyException e) {
            return ResultDTO.fail("DATA_REPEAT", "数据重复");
        }
    }

    @Transactional
    @Override
    public ResultDTO<ItemBaseBatchCreateResponse> batchCreateItem(ItemBaseBatchCreateRequest request) {
        ItemBaseBatchCreateResponse response = ItemBaseBatchCreateResponse.builder()
                .responses(request.getRequests().stream().map(this::createItem).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

    @Transactional
    @Override
    public ResultDTO<ItemBaseDeleteResponse> deleteItem(ItemBaseDeleteRequest request) {
        itemMapper.deleteById(request.getId());

        ItemBaseDeleteResponse response = ItemBaseDeleteResponse.builder()
                .request(request)
                .build();
        return ResultDTO.success(response);
    }

    @Transactional
    @Override
    public ResultDTO<ItemBaseBatchDeleteResponse> batchDeleteItem(ItemBaseBatchDeleteRequest request) {
        ItemBaseBatchDeleteResponse response = ItemBaseBatchDeleteResponse.builder()
                .responses(request.getRequests().stream().map(this::deleteItem).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

    @Transactional
    @Override
    public ResultDTO<ItemBaseResponse> updateItem(ItemBaseUpdateRequest request) {
        try {
            Item item = itemBaseUpdateRequestToEntityConverter.convert(request);
            itemMapper.updateById(item);
            ItemBaseResponse response = itemToBaseResponseConverter.convert(item);
            return ResultDTO.success(response);
        } catch (DuplicateKeyException e) {
            return ResultDTO.fail("DATA_REPEAT", "数据重复");
        }
    }

    @Transactional
    @Override
    public ResultDTO<ItemBaseBatchUpdateResponse> batchUpdateItem(ItemBaseBatchUpdateRequest request) {
        ItemBaseBatchUpdateResponse response = ItemBaseBatchUpdateResponse.builder()
                .requests(request.getRequests().stream().map(this::updateItem).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

    @Override
    public ResultDTO<ItemBaseResponse> getItemById(ItemBaseGetByIdRequest request) {
        Item item = itemMapper.selectById(request.getId());
        if (item == null) {
            return ResultDTO.success();
        }

        ItemBaseResponse response = itemToBaseResponseConverter.convert(item);
        return ResultDTO.success(response);
    }

    @Override
    public ResultDTO<ItemBaseListResponse> getItemByIds(ItemBaseGetByIdsRequest request) {
        List<Item> list = request.getIds().stream().map(id -> itemMapper.selectById(id)).collect(Collectors.toList());
        return ResultDTO.success(ItemBaseListResponse.builder()
                .items(list.stream().map(item -> itemToBaseResponseConverter.convert(item)).collect(Collectors.toList()))
                .build());
    }

    @Override
    public Item getItemByKey(ItemBaseGetByKeyRequest request) {
        return itemMapper.selectOne(new QueryWrapper<>(itemBaseGetByKeyRequestToEntityConverter.convert(request)));
    }

    @Override
    public ResultDTO<ItemBaseListResponse> listItem(ItemBaseListRequest request) {
        QueryWrapper<Item> wrapper = new QueryWrapper<>(itemBaseListRequestToEntityConverter.convert(request));
        if (StringUtils.isNotEmpty(request.getOrderByKey())) {
            wrapper.orderByDesc(request.getOrderByKey());
        }

        List<Item> items = itemMapper.selectList(wrapper);

        ItemBaseListResponse response = ItemBaseListResponse.builder()
                .items(items.stream().map(itemToBaseResponseConverter::convert).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

    @Override
    public ResultDTO<ItemBaseListResponse> listAllItem(OrderBy orderBy) {
        ItemBaseListRequest itemRequest = ItemBaseListRequest.builder().build();
        itemRequest.setOrderByKey(orderBy.getOrderByKey());
        return listItem(itemRequest);
    }

    @Override
    public ResultDTO<PageResult<ItemBaseResponse>> listItemPage(ItemBaseListPageRequest request) {
        Page<Item> page = new Page<>(request.getPageNum(), request.getPageSize(), true);

        QueryWrapper<Item> wrapper = new QueryWrapper<>(itemBaseListPageRequestToEntityConverter.convert(request));
        if (StringUtils.isNotEmpty(request.getOrderByKey())) {
            if (request.getOrderByDesc() != null && request.getOrderByDesc().booleanValue() == false) {
                wrapper.orderByAsc(request.getOrderByKey());
            } else {
                wrapper.orderByDesc(request.getOrderByKey());
            }
        }

        IPage<Item> pageResult = itemMapper.selectPage(page, wrapper);

        PageResult<ItemBaseResponse> response = new PageResult(
                pageResult.getTotal(), pageResult.getPages(), pageResult.getCurrent(), pageResult.getSize(),
                pageResult.getRecords().stream().map(itemToBaseResponseConverter::convert).collect(Collectors.toList()));
        return ResultDTO.success(response);
    }

    @Override
    public ResultDTO<ItemBaseBatchCreateResponse> batchCreateItemAsync(ItemBaseBatchCreateRequest request) {
        ItemBaseBatchCreateResponse response = ItemBaseBatchCreateResponse.builder()
                .responses(request.getRequests().parallelStream().map(this::createItem).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

    @Override
    public ResultDTO<ItemBaseBatchDeleteResponse> batchDeleteItemAsync(ItemBaseBatchDeleteRequest request) {
        ItemBaseBatchDeleteResponse response = ItemBaseBatchDeleteResponse.builder()
                .responses(request.getRequests().parallelStream().map(this::deleteItem).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

    @Override
    public ResultDTO<ItemBaseBatchUpdateResponse> batchUpdateItemAsync(ItemBaseBatchUpdateRequest request) {
        ItemBaseBatchUpdateResponse response = ItemBaseBatchUpdateResponse.builder()
                .requests(request.getRequests().parallelStream().map(this::updateItem).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

}
